package club.jdiy.dev.view;

import club.jdiy.admin.freemarker.func.CutText;
import club.jdiy.admin.freemarker.func.GetDictInfo;
import club.jdiy.admin.freemarker.func.Grant;
import club.jdiy.admin.freemarker.func.HasRole;
import club.jdiy.core.AdminContext;
import club.jdiy.utils.DateUtils;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.*;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.SpringTemplateLoader;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.Locale;

@Component
public class FtlInvoker {

    public void invoke(String view, HttpServletResponse response, Map<String, Object> map) throws IOException, TemplateException {
        Template template = configuration.getTemplate(view + ".zlt");
        configuration.setSharedVariable("getDictInfo", getDictInfo);
        template.process(map, response.getWriter());
    }

    public FtlParser getParser() {
        FtlParser elp = new FtlParser(uiConfiguration, null);
        elp.addVariable("ctx", context.getContextPathURL());
        elp.addVariable("user", context.getCurrentUserRs());
        elp.addVariable("datetime", DateUtils.fmt_datetime.format(LocalDateTime.now()));
        elp.addVariable("date", DateUtils.fmt_date.format(LocalDate.now()));
        elp.addVariable("intDay", DateUtils.intDay());//某些情况要判断距今天之前或之后多少天用．不要删除
        return elp;
    }

    @PostConstruct
    public void init() {
        configuration = createFtlConf();
        TemplateLoader classTemplateLoader = new ClassTemplateLoader(this.getClass(), ".");
        MultiTemplateLoader mt = new MultiTemplateLoader(new TemplateLoader[]{
                new ClassTemplateLoader(View.class, "tpl/"),
                classTemplateLoader,
                new SpringTemplateLoader(new DefaultResourceLoader(), "classpath:/")
        });
        configuration.setTemplateLoader(mt);

        //界面配置中,开发人员的模板:
        uiConfiguration = createFtlConf();
    }

    private Configuration createFtlConf() {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
        configuration.setNumberFormat("0.##");
        configuration.setDateFormat("yyyy-MM-dd");
        configuration.setTimeFormat("HH:mm:ss");
        configuration.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
        configuration.setLocale(Locale.CHINA);
        configuration.setDefaultEncoding("utf-8");
        configuration.setOutputEncoding("utf-8");
        configuration.setClassicCompatible(true);
        configuration.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
        configuration.setTemplateUpdateDelayMilliseconds(3000);
        configuration.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
        configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_31) {
            @Override
            public TemplateModel wrap(Object object) throws TemplateModelException {

                if (object instanceof LocalDate) {
                    return new SimpleDate(Date.valueOf((LocalDate) object));
                }
                if (object instanceof LocalTime) {
                    return new SimpleDate(Time.valueOf((LocalTime) object));
                }
                if (object instanceof LocalDateTime) {
                    return new SimpleDate(Timestamp.valueOf((LocalDateTime) object));
                }
                return super.wrap(object);
            }
        });

        //自定义函数:
        configuration.setSharedVariable("cut", cutText);
        configuration.setSharedVariable("grant", grant);
        configuration.setSharedVariable("hasRole", hasRole);
        return configuration;
    }

    private Configuration configuration;
    private Configuration uiConfiguration;


    @Resource
    protected AdminContext context;
    @Resource
    private Grant grant;
    @Resource
    private HasRole hasRole;
    @Resource
    private CutText cutText;
    @Resource
    private GetDictInfo getDictInfo;
}
